import java.io.*;

/**
 * Project: MLBPlayer Database
 * This class takes care of parsing the csv file.
 * NOTE: It is up the class that instantiates this parser
 * to call the close(), otherwise memory leaks will abound!
 *
 * @author jonb88
 * @version Oct 01, 2009
 */
public class RndAParser
{
	//used to read or write to a file
	private RandomAccessFile _parser;
	
	/**
	 * This constructor sets up the RandomAccessFile parser.
	 * Calls: setFilePointer( long )
	 * 
	 * @param file is the path of the file needed to be parsed.
	 * @param filePtr allows the user to initially set the file pointer.
	 */
	public RndAParser( String file, long filePtr )
	{
		try
		{
			_parser = new RandomAccessFile( new File( file ), "rw" );
			
		}
		catch ( FileNotFoundException e )
		{
			System.out.println( "Cound not find file: " + file );
			System.out.println( "Occured in: " + this.getClass() );
		}
		setFilePointer( filePtr );
	}
	
	/**
	 * This method specifically combats the problem where I must check
	 * the validity of the filepath. To do this I look for a 
	 * FileNotFoundException and throw that back onto whatever
	 * class is using this parser.
	 * Calls: setFilePointer( long )
	 * 
	 * @param file is a file to parse.
	 * @param filePtr is the offset in the file to start at.
	 * @param readWrite is a String specifying 
	 * whether this parse is reading a file or writing to it.
	 * @throws FileNotFoundException if this file doesn't exist
	 * the using class must deal with it gracefully!
	 */
	public RndAParser( File file, long filePtr,
			String readWrite ) throws FileNotFoundException
	{
		//_file = file;
		try
		{
			_parser = new RandomAccessFile( file, readWrite );
		}
		catch ( FileNotFoundException e )
		{
			throw new FileNotFoundException();
		}
		catch ( IllegalArgumentException e )
		{
			System.out.println( "Error: IllegalArgumentException occured while"
					+ " trying to setup the RndAParser(), "
					+ "you can only use 'r', 'rw' !");
			System.out.println( "Occured in: " + this.getClass() );
		}
		setFilePointer( filePtr );
	}
	
	/**
	 * This a lazy method because I don't feel like try/catching
	 * around every single place I get the filePointer.
	 * 
	 * @return the file pointer, if an IOException is thrown it returns -1.
	 */
	public long getFilePointer()
	{
		//used to hold where the read/write pointer is sitting
		long ptr = -1L;
		
		try
		{
			ptr = _parser.getFilePointer();
		}
		catch ( IOException e )
		{
			System.out.println( "Error: IOException occured while"
					+ " trying to _getFilePointer(), "
					+ "the stream may not be open!");
			System.out.println( "Occured in: " + this.getClass() );
		}
		return ptr;
	}
	
	/**
	 * This method is a lazy method to take care of the try catching
	 * when getting the length of the file.
	 * 
	 * @return a long representing the lenght of the file.
	 * If an exception occurs -1 is returned.
	 */
	private long _getFileLength()
	{
		//holds the length of the file being read/written
		long length = -1L;
		
		try
		{
			length = _parser.length();
		}
		catch( IOException e )
		{
			System.out.println( "Error: IOException occured while"
					+ " trying to _getFileLength()" );
			System.out.println( "Occured in: " + this.getClass() );
		}
		return length;
	}
	
	/**
	 * This method returns the length of the file.
	 * Calls: _getFileLength()
	 * 
	 * @return a long representing the length of the file.
	 */
	public long getFileLength()
	{
		return _getFileLength();
	}
	
	/**
	 * This method sets the file pointer.
	 * 
	 * @param ptr is a long representing the byte in the file.
	 */
	public void setFilePointer( long ptr )
	{
		try
		{
			_parser.seek( ptr );
		}
		catch ( IOException e )
		{
			System.out.println( "Error: You tried to seek to a "
					+ "negative position\n or there was an IOException" );
			System.out.println( "Occured in: " + this.getClass() );
		}
	}
	
	/**
	 * This method returns the file in a string.
	 * 
	 * @return str is the entire file.
	 */
	public String readInFile()
	{
		//holds the current line just read in
		String str = "";
		
		try
		{
			while ( hasNextLine() )
				str += _parser.readLine() + "\n";
		}
		catch ( IOException e )
		{
			System.out.println( "Error: IOException occured while"
					+ " trying to _parseNewline()" );
			System.out.println( "Occured in: " + this.getClass() );
		}
				
		return str;
	}
	
	/**
	 * This method returns whether the parser has reached
	 * the end of the file or not.
	 * 
	 * @return true if the parser is not at the end of the file.
	 */
	public boolean hasNextLine()
	{
		return ( getFilePointer() < _getFileLength() ) ? true : false;
	}
		
	/**
	 * This method writes a string to the file.
	 * 
	 * @param text is the string to write to the file.
	 */
	public void writeTF( String text )
	{
		try
		{
			_parser.writeBytes( text );
		}
		catch ( IOException e )
		{
			System.out.println( "Error: IOException occured while"
					+ " trying to writeTF()");
			System.out.println( "Occured in: " + this.getClass() );
		}
	}
	
	/**
	 * This method closes the file stream.
	 */
	public void close()
	{
		try
		{
			_parser.close();
		}
		catch ( IOException e )
		{
			System.out.println( "Error: IOException occured while"
					+ " trying to close()");
			System.out.println( "Occured in: " + this.getClass() );
		}
	}
}
